home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / mach / amiga / scsi9091.lzh / try_unit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-24  |  2.9 KB  |  111 lines

  1. #include <exec/types.h>
  2. #include <exec/nodes.h>
  3. #include <exec/resident.h>
  4. #include <exec/memory.h>
  5. #include <exec/devices.h>
  6. #include <libraries/expansionbase.h>
  7. #include <libraries/configvars.h>
  8.  
  9. /*
  10.  * Set SysBase to a local variable, that loads directly from 4 when it
  11.  * has to be reloaded
  12.  */
  13. #define BASE_EXT_DECL
  14. #define BASE_NAME (*(void **)4)
  15. #include <inline/exec.h>
  16.  
  17. #include "device.h"
  18.  
  19. /*
  20.  * Check a given scsi unit for an attached device.
  21.  */
  22.  
  23. extern void unit_start(struct scsi_unit *unit);
  24. DECL_DPRINTF;
  25.  
  26. void
  27. try_unit(struct scsi_dev *dev, int unit)
  28. {
  29.   /* this checks, whether an scsi-device responds to the given 
  30.    * unit number.
  31.    * if there is a unit responding, a unit task is created */
  32.   ubyte cmd[12];
  33.   struct scsi_msg *sc = &dev->sc_hmessage;
  34.   struct SCSICmd scd;
  35.   ulong sense_buf;
  36.   struct scsi_unit *su;
  37.   struct Task *tcb;
  38.   int retries;
  39.  
  40.   dev->sc_units[unit] = 0;
  41.  
  42. #ifdef DEBUG
  43. /*  if (unit != 2 && unit != 4) return;*/
  44. #endif
  45.  
  46.   sc->scm_message.mn_ReplyPort = &dev->sc_msgport;
  47.   
  48.   /* first do a TEST UNIT READY, if there is no device of that unit
  49.    * the answer will be a select-timeout */
  50.    
  51.   cmd[0] = cmd[1] = cmd[2] = cmd[3] = cmd[4] = cmd[5] = 0;
  52.   sc->scm_scsi_cmd = &scd;
  53.   
  54.   scd.scsi_Length = 0;
  55.   scd.scsi_Command = cmd;
  56.   scd.scsi_CmdLength = 6;
  57.   /* swallow any UNIT ATTENTION responses */
  58.   scd.scsi_Flags = SCSIF_READ|SCSIF_OLDAUTOSENSE;
  59.   scd.scsi_SenseData = (UBYTE *)&sense_buf;
  60.   scd.scsi_SenseLength = 4;
  61.  
  62.   retries = 60;
  63.   do
  64.     {
  65.       sc->scm_cmd = SCM_CMD_EXEC_SCSI;
  66.       sc->scm_unit = unit;
  67.   
  68.       PutGetMsg(dev->sc_hmsgport, &dev->sc_msgport, (struct Message *)sc);
  69.     }
  70.   while ((sc->scm_cmd == HFERR_DMA || sc->scm_cmd == HFERR_Phase) && retries-- >= 0) ;
  71.  
  72.   /* in these two cases, a unit is attached to the bus, no matter
  73.    * whether it is currently ready or not */
  74.   if (sc->scm_cmd == 0 || sc->scm_cmd == HFERR_BadStatus)
  75.     {
  76.       /* now set up a task for this unit */
  77.       
  78. DPRINTF(("unit %ld ok, starting unit task", unit));
  79.  
  80.       su = (struct scsi_unit *)AllocMem(sizeof(*su), MEMF_CLEAR|MEMF_PUBLIC);
  81.       dev->sc_units[unit] = su;
  82.       
  83.       su->scu_unitnum = unit;
  84.       su->scu_device = dev;
  85.       su->scu_hmsgport = dev->sc_hmsgport;
  86.       sc = &su->scu_hmessage;
  87.       
  88.       tcb = &su->scu_tcb;
  89.       tcb->tc_SPLower = (APTR)su->scu_stack;
  90.       tcb->tc_SPUpper = (APTR)(su->scu_stack + UNIT_STACKSIZE);
  91.       tcb->tc_SPReg = (APTR)(tcb->tc_SPUpper - 4);
  92.       /* pass the child the unit pointer */
  93.       *(struct scsi_unit **)tcb->tc_SPReg = su;
  94.     
  95.       tcb->tc_Node.ln_Type = NT_TASK;        
  96.       tcb->tc_Node.ln_Pri = UNIT_PRIORITY;
  97.       tcb->tc_Node.ln_Name = UNIT_NAME;
  98.     
  99.       NewList(&tcb->tc_MemEntry);
  100.     
  101.       AddTask(tcb, unit_start, 0);
  102.  
  103.       /* the unit now figures out itself, of which type it is */
  104. DPRINTF(("unit %ld TEST READY ok", unit));
  105.     }
  106.   else
  107. DPRINTF(("unit %ld TEST READY negativ", unit));
  108. }
  109.  
  110.  
  111.